﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.Serialization;
using RiskMan.Config;
using RiskMan.DataClass.Models.NotBasModels;


namespace RiskMan.DataClass.Stops
{
    [Serializable]
    public class StopsModel : INotifyPropertyChanged, ISerializable
    {
        #region private
        #region BaseSettings

        private bool _check;
        private string _account;
        private bool _isStart;
        private string _clientCode;
        private string _typeStop;
        private string _typeCalculation;
        private string _typePriceForStop;
        private Guid _guidRobot;
        private string _instrument;
        private bool _typeSingleOrMultiStopl;

        #endregion BaseSettings

        #region StopLimit

        private double _stopLimitOtstup;
        private string _stopLimitOtstupType;
        private double _stopLimitFromEnterMoney;
        private double _stopLimitSpred;
        private string _stopLimitSpredType;
        private bool _stopLimitIsMarketOrder;
        private double _stopLimitBreakeven;
        private string _stopLimitBreakevenType;
        private double _stopLimitBreakOtstup;

        #endregion StopLimit

        #region TakeProfit

        private double _takeProfitPriceActivation;
        private string _takeProfitPriceActivationType;
        private double _takeProfitFromEnterMoney;
        private double _takeProfitOtstupMinMax;
        private string _takeProfitOtstupMinMaxType;
        private double _takeProfitSpred;
        private string _takeProfitSpredType;
        private bool _takeProfitIsMarketOrder;

        #endregion TakeProfit

        #region KillAndRemoveOrderFromStopOrder

        private string _killOrderType;
        private int _timeWaitForKillOrderFromStop;
        private double _spredWaitForKillOrderFromStop;

        #endregion KillAndRemoveOrderFromStopOrder

        #region LimitOrder

        private double _limitPrice;
        private string _limitPriceType;
        private double _limitFromEnterMoney;

        #endregion LimitOrder

        private ObservableCollection<TradesOpen> _tradeList;
        private int _currentPos;
        private double _currentPrice;

        #endregion

        #region public

        #region SettingsForCmbx

        //private List<String> _TypeStopList = new List<String>() 
        //{
        //    Cfg.StopLimit,
        //    Cfg.TakeProfit,
        //    Cfg.StopTakeOrder,
        //    Cfg.LinkedOrder,
        //    Cfg.TakeProfitLimitOrder
        //};

        //private List<String> _TypePriceList = new List<String>() 
        //{
        //    Cfg.ValutPrice,
        //    Cfg.Persent
        //};

        //private List<String> _TypePriceForStopsList = new List<String>() 
        //{
        //    Cfg.StopFromLastPriceDeal, 
        //    Cfg.StopFromAvaregePriceDeal,
        //};

        //private List<String> _TypeCalculationList = new List<String>() 
        //{
        //    Cfg.StopTypeCalculationBySetting, 
        //    Cfg.StopTypeCalculationFromDeposit
        //};

        //private List<String> _TypeKillAndRemoveLimitFromStopLimitList = new List<String>()
        //{
        //    Cfg.Unknown,
        //    Cfg.StopKillAndRemoveFromTime,
        //    Cfg.StopKillAndRemoveFromSpred,
        //    Cfg.StopKillAndRemoveFromTimeAndSpred
        //};


        #endregion SettingsForCmbx
        
        #region BaseSettings

        public bool Check
        {
            get { return _check; }
            set
            {
                if (_check != value)
                {
                    _check = value;
                    RaisePropertyChanged("Check");
                }
            }

        }
        public String Account
        {
            get { return _account; }
            set
            {
                if (_account != value)
                {
                    _account = value;
                    RaisePropertyChanged("Account");
                }
            }
        }
        public String ClientCode
        {
            get { return _clientCode; }
            set
            {
                if (_clientCode != value)
                {
                    _clientCode = value;
                    RaisePropertyChanged("ClientCode");
                }
            }

        }
        /// <summary>
        /// Инструмент, по которому выставляется стоп
        /// </summary>
        public String Instrument
        {
            get { return _instrument; }
            set
            {
                if (_instrument != value)
                {
                    _instrument = value;
                    RaisePropertyChanged("Instrument");
                }
            }
        }
        public bool IsStart
        {
            get { return _isStart; }
            set
            {
                if (_isStart != value)
                {
                    _isStart = value;
                    RaisePropertyChanged("IsStart");
                }
            }
        }
        /// <summary>
        /// Стоп-лимит, Связання заявка и т.д.
        /// </summary>
        public String TypeStop
        {
            get { return _typeStop; }
            set
            {
                if (_typeStop != value)
                {
                    _typeStop = value;
                    RaisePropertyChanged("TypeStop");
                }
            }
        }

        /// <summary>
        /// Рассчет ведется величины стопа от депозита на заданную величину риска в процентах или по заданными параметрам отступа и спрэда
        /// </summary>
        public String TypeCalculation
        {
            get { return _typeCalculation; }
            set
            {
                if (_typeCalculation != value)
                {
                    _typeCalculation = value;
                    RaisePropertyChanged("TypeCalculation");
                }
            }
        }
        /// <summary>
        /// Выставляемый стоп рассчитывается от цены последней сделки или от средней цены позиции.
        /// </summary>
        public string TypePriceForStop
        {
            get { return _typePriceForStop; }
            set
            {
                if (_typePriceForStop != value)
                {
                    _typePriceForStop = value;
                    RaisePropertyChanged("TypePriceForStop");
                }
            }
        }
        /// <summary>
        /// Уникальный номер стопа
        /// </summary>
        public Guid GuidRobot
        {
            get { return _guidRobot; }
            set
            {
                if (_guidRobot != value)
                {
                    _guidRobot = value;
                    RaisePropertyChanged("GuidRobot");
                }
            }
        }


        /// <summary>
        /// Стоп выставляется на каждую исполненную или частично исполненную заявку или единый на всю позицию
        /// </summary>
        public bool TypeSingleOrMultiStopl
        {
            get { return _typeSingleOrMultiStopl; }
            set
            {
                if (_typeSingleOrMultiStopl != value)
                {
                    _typeSingleOrMultiStopl = value;
                    RaisePropertyChanged("TypeSingleOrMultiStopl");
                }
            }
        }

        #endregion BaseSettings

        #region StopLimit

        /// <summary>
        /// Расстояние между будущим стоп и ценой расчета сделки
        /// </summary>
        public double StopLimitOtstup
        {
            get { return _stopLimitOtstup; }
            set
            {
                if (_stopLimitOtstup != value)
                {
                    _stopLimitOtstup = value;
                    RaisePropertyChanged("StopOtst");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string StopLimitOtstupType
        {
            get { return _stopLimitOtstupType; }
            set
            {
                if (_stopLimitOtstupType != value)
                {
                    _stopLimitOtstupType = value;
                    RaisePropertyChanged("StopLimitOtstupType");
                }
            }
        }


        /// <summary>
        /// Стоп рассчитывается в зависимости от депозита. Процент риска рассчитывается для каждой позиции, при мультистопе
        /// </summary>
        public double StopLimitFromEnterMoney
        {
            get { return _stopLimitFromEnterMoney; }
            set
            {
                if (_stopLimitFromEnterMoney != value)
                {
                    _stopLimitFromEnterMoney = value;
                    RaisePropertyChanged("StopLimitFromEnterMoney");
                }
            }
        }

        /// <summary>
        /// Спред в стоп-лимит заявке. Разница между ценой активацией стоп-лимит и цены выставления заявки.
        /// </summary>
        public double StopLimitSpred
        {
            get { return _stopLimitSpred; }
            set
            {
                if (_stopLimitSpred != value)
                {
                    _stopLimitSpred = value;
                    RaisePropertyChanged("StopSprd");
                }
            }
        }

        /// <summary>
        /// тип проценты или валюта цены
        /// </summary>
        public string StopLimitSpredType
        {
            get { return _stopLimitSpredType; }
            set
            {
                if (_stopLimitSpredType != value)
                {
                    _stopLimitSpredType = value;
                    RaisePropertyChanged("StopLimitSpredType");
                }
            }
        }

        /// <summary>
        /// исполнять по рынку или нет
        /// </summary>
        public bool StopLimitIsMarketOrder
        {
            get { return _stopLimitIsMarketOrder; }
            set
            {
                if (_stopLimitIsMarketOrder != value)
                {
                    _stopLimitIsMarketOrder = value;
                    RaisePropertyChanged("StopLimitIsMarketOrder");
                }
            }
        }
        /// <summary>
        /// Величина ухода цены от цены сделки и перенос стопа в безубыток
        /// </summary>
        public double StopLimitBreakeven
        {
            get { return _stopLimitBreakeven; }
            set
            {
                if (_stopLimitBreakeven != value)
                {
                    _stopLimitBreakeven = value;
                    RaisePropertyChanged("Breakeven");
                }
            }
        }

        /// <summary>
        /// проценты или валюта цены
        /// </summary>
        public string StopLimitBreakevenType
        {
            get { return _stopLimitBreakevenType; }
            set
            {
                if (_stopLimitBreakevenType != value)
                {
                    _stopLimitBreakevenType = value;
                    RaisePropertyChanged("StopLimitBreakevenType");
                }
            }
        }

        /// <summary>
        /// Величина отступа для безубытка, для учета комиссии и проскальзывания
        /// </summary>
        public double StopLimitBreakOtstup
        {
            get { return _stopLimitBreakOtstup; }
            set
            {
                if (_stopLimitBreakOtstup != value)
                {
                    _stopLimitBreakOtstup = value;
                    RaisePropertyChanged("StopLimitBreakOtstup");
                }
            }
        }

        #endregion StopLimit

        #region TakeProfit

        /// <summary>
        /// Цена активации тейк-профит.
        /// </summary>
        public Double TakeProfitPriceActivation
        {
            get { return _takeProfitPriceActivation; }
            set
            {
                if (_takeProfitPriceActivation != value)
                {
                    _takeProfitPriceActivation = value;
                    RaisePropertyChanged("TakePrAc");
                }
            }
        }

        /// <summary>
        /// Тип проценты или валюта цены
        /// </summary>
        public string TakeProfitPriceActivationType
        {
            get { return _takeProfitPriceActivationType; }
            set
            {
                if (_takeProfitPriceActivationType != value)
                {
                    _takeProfitPriceActivationType = value;
                    RaisePropertyChanged("TakeProfitPriceActivationType");
                }
            }
        }

        /// <summary>
        /// Отступ для min/max
        /// </summary>
        public Double TakeProfitOtstupMinMax
        {
            get { return _takeProfitOtstupMinMax; }
            set
            {
                if (_takeProfitOtstupMinMax != value)
                {
                    _takeProfitOtstupMinMax = value;
                    RaisePropertyChanged("TakeOtst");
                }
            }
        }

        /// <summary>
        /// Тип проценты или валюта цены
        /// </summary>
        public string TakeProfitOtstupMinMaxType
        {
            get { return _takeProfitOtstupMinMaxType; }
            set
            {
                if (_takeProfitOtstupMinMaxType != value)
                {
                    _takeProfitOtstupMinMaxType = value;
                    RaisePropertyChanged("TakeProfitOtstupMinMaxType");
                }
            }
        }
        /// <summary>
        /// Расчет выставляемого тейка ведется от цены входящих средств
        /// </summary>
        public double TakeProfitFromEnterMoney
        {
            get { return _takeProfitFromEnterMoney; }
            set
            {
                if (_takeProfitFromEnterMoney != value)
                {
                    _takeProfitFromEnterMoney = value;
                    RaisePropertyChanged("TakeProfitFromEnterMoney");
                }
            }
        }

        /// <summary>
        /// Защитный спрэд
        /// </summary>
        public Double TakeProfitSpred
        {
            get { return _takeProfitSpred; }
            set
            {
                if (_takeProfitSpred != value)
                {
                    _takeProfitSpred = value;
                    RaisePropertyChanged("TakeSprd");
                }
            }
        }

        /// <summary>
        /// Тип проценты или валюта цены
        /// </summary>
        public string TakeProfitSpredType
        {
            get { return _takeProfitSpredType; }
            set
            {
                if (_takeProfitSpredType != value)
                {
                    _takeProfitSpredType = value;
                    RaisePropertyChanged("TakeProfitSpredType");
                }
            }
        }

        /// <summary>
        /// Исполнять ли тейк-профит по рынку
        /// </summary>
        public bool TakeProfitIsMarketOrder
        {
            get { return _takeProfitIsMarketOrder; }
            set
            {
                if (_takeProfitIsMarketOrder != value)
                {
                    _takeProfitIsMarketOrder = value;
                    RaisePropertyChanged("TakeProfitIsMarketOrder");
                }
            }
        }

        #endregion TakeProfit

        #region KillAndRemoveOrderFromStopOrder


        /// <summary>
        /// Тип снятие и исполнение лимитной заявки от ордера
        /// </summary>
        public string KillOrderType
        {
            get { return _killOrderType; }
            set
            {
                if (_killOrderType != value)
                {
                    _killOrderType = value;
                    RaisePropertyChanged("KillOrderType");
                }
            }
        }

        /// <summary>
        /// Время через которое будет произведено снятие и исполнение лимитной заявки от стоп-ордера
        /// </summary>
        public int TimeWaitForKillOrderFromStop
        {
            get { return _timeWaitForKillOrderFromStop; }
            set
            {
                if (_timeWaitForKillOrderFromStop != value)
                {
                    _timeWaitForKillOrderFromStop = value;
                    RaisePropertyChanged("TimeWaitForKillOrderFromStop");
                }
            }
        }

        /// <summary>
        /// Отклонение от цены сделки, после првышения которого будет произведено снятие и исполнение лимитной заявки от стоп-ордера
        /// </summary>
        public double SpredWaitForKillOrderFromStop
        {
            get { return _spredWaitForKillOrderFromStop; }
            set
            {
                if (_spredWaitForKillOrderFromStop != value)
                {
                    _spredWaitForKillOrderFromStop = value;
                    RaisePropertyChanged("SpredWaitForKillOrderFromStop");
                }
            }
        }

        #endregion KillAndRemoveOrderFromStopOrder

        #region LimitOrder

        /// <summary>
        /// Цена для лимитной заявки на профит
        /// </summary>
        public double LimitPrice
        {
            get { return _limitPrice; }
            set
            {
                if (_limitPrice != value)
                {
                    _limitPrice = value;
                    RaisePropertyChanged("LimitPrice");
                }
            }
        }

        /// <summary>
        /// Тип проценты или валюта цены
        /// </summary>
        public string LimitPriceType
        {
            get { return _limitPriceType; }
            set
            {
                if (_limitPriceType != value)
                {
                    _limitPriceType = value;
                    RaisePropertyChanged("LimitPriceType");
                }
            }
        }
        /// <summary>
        /// Выставление заявки в процентах от входящих средств
        /// </summary>
        public double LimitFromEnterMoney
        {
            get { return _limitFromEnterMoney; }
            set
            {
                if (_limitFromEnterMoney != value)
                {
                    _limitFromEnterMoney = value;
                    RaisePropertyChanged("LimitFromEnterMoney");
                }
            }
        }

        #endregion LimitOrder

        public int CurrentPos
        {
            get { return _currentPos; }
            set
            {
                if (_currentPos != value)
                {
                    _currentPos = value;
                    RaisePropertyChanged("CurrentPos");
                }
            }
        }
        public double CurrentPrice
        {
            get { return _currentPrice; }
            set
            {
                if (_currentPrice != value)
                {
                    _currentPrice = value;
                    RaisePropertyChanged("CurrentPrice");
                }
            }
        }

        //public List<String> TypeStopList
        //{
        //    get { return _TypeStopList; }
        //    set
        //    {
        //        if (_TypeStopList != value)
        //        {
        //            _TypeStopList = value;
        //            RaisePropertyChanged("TypeStopList");
        //        }
        //    }
        //}

        //public List<String> TypePriceList
        //{
        //    get { return _TypePriceList; }
        //    set
        //    {
        //        if (_TypePriceList != value)
        //        {
        //            _TypePriceList = value;
        //            RaisePropertyChanged("TypePriceList");
        //        }
        //    }
        //}

        //public List<String> TypePriceForStopsList
        //{
        //    get { return _TypePriceForStopsList; }
        //    set
        //    {
        //        if (_TypePriceForStopsList != value)
        //        {
        //            _TypePriceForStopsList = value;
        //            RaisePropertyChanged("TypePriceForStopsList");
        //        }
        //    }
        //}
        
        ///// <summary>
        ///// 
        ///// </summary>
        //public List<String> TypeCalculationList
        //{
        //    get { return _TypeCalculationList; }
        //    set
        //    {
        //        if (_TypeCalculationList != value)
        //        {
        //            _TypeCalculationList = value;
        //            RaisePropertyChanged("TypeCalculationList");
        //        }
        //    }
        //}

        ///// <summary>
        ///// 
        ///// </summary>

        //public List<String> TypeKillAndRemoveLimitFromStopLimitList
        //{
        //    get { return _TypeKillAndRemoveLimitFromStopLimitList; }
        //    set
        //    {
        //        if (_TypeKillAndRemoveLimitFromStopLimitList != value)
        //        {
        //            _TypeKillAndRemoveLimitFromStopLimitList = value;
        //            RaisePropertyChanged("TypeKillAndRemoveLimitFromStopLimitList");
        //        }
        //    }
        //}

        /// <summary>
        /// коллекция активнных и исполненных сделок на открытие и закрытие позиции
        /// </summary>
        
        public ObservableCollection<TradesOpen> TradeList
        {
            get { return _tradeList; }
            set
            {
                if (_tradeList != value)
                {
                    _tradeList = value;
                    RaisePropertyChanged("TradeList");
                }
            }
        }

        #endregion

        #region OnPropertyChanged


        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        public StopsModel() { }

        public StopsModel(SerializationInfo info, StreamingContext context)
        {
            #region BaseSettings

            Check = info.GetBoolean("Check");
            Account = info.GetString("Account");
            ClientCode = info.GetString("ClientCode");
            Instrument = info.GetString("Instrument");
            TypeStop = info.GetString("TypeStop");
            TypeCalculation = info.GetString("TypeCalculation");
            TypePriceForStop = info.GetString("TypePriceForStop");
            TypeSingleOrMultiStopl = info.GetBoolean("TypeSingleOrMultiStopl");

            #endregion BaseSettings

            #region StopLimit

            StopLimitOtstup = info.GetDouble("StopLimitOtstup");
            StopLimitOtstupType = info.GetString("StopLimitOtstupType");
            StopLimitFromEnterMoney = info.GetDouble("StopLimitFromEnterMoney");
            StopLimitSpred = info.GetDouble("StopLimitSpred");
            StopLimitSpredType = info.GetString("StopLimitSpredType");
            StopLimitIsMarketOrder = info.GetBoolean("StopLimitIsMarketOrder");
            StopLimitBreakeven = info.GetDouble("StopLimitBreakeven");
            StopLimitBreakevenType = info.GetString("StopLimitBreakevenType");
            StopLimitBreakOtstup = info.GetDouble("StopLimitBreakOtstup");

            #endregion StopLimit

            #region TakeProfit

            TakeProfitPriceActivation = info.GetDouble("TakeProfitPriceActivation");
            TakeProfitPriceActivationType = info.GetString("TakeProfitPriceActivationType");
            TakeProfitOtstupMinMax = info.GetDouble("TakeProfitOtstupMinMax");
            TakeProfitOtstupMinMaxType = info.GetString("TakeProfitOtstupMinMaxType");
            TakeProfitSpred = info.GetDouble("TakeProfitSpred");
            TakeProfitSpredType = info.GetString("TakeProfitSpredType");
            TakeProfitFromEnterMoney = info.GetDouble("TakeProfitFromEnterMoney");
            TakeProfitIsMarketOrder = info.GetBoolean("TakeProfitIsMarketOrder");

            #endregion TakeProfit

            #region KillAndRemoveOrderFromStopOrder

            KillOrderType = info.GetString("KillOrderType");
            TimeWaitForKillOrderFromStop = info.GetInt32("TimeWaitForKillOrderFromStop");
            SpredWaitForKillOrderFromStop = info.GetDouble("SpredWaitForKillOrderFromStop");

            #endregion KillAndRemoveOrderFromStopOrder

            #region LimitOrder
            LimitPrice = info.GetDouble("LimitPrice");
            LimitPriceType = info.GetString("LimitPriceType");
            LimitFromEnterMoney = info.GetDouble("LimitFromEnterMoney");
            #endregion
            //TypeStopList = ( List<String> ) info.GetValue( "TypeStopList", typeof( List<String> ) );
            //TypePriceList = ( List<String> ) info.GetValue( "TypeRaschList", typeof( List<String> ) );
            CurrentPos = info.GetInt32("CurrentPos");
            CurrentPrice = info.GetDouble("CurrentPrice");

        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            #region BaseSettings

            info.AddValue("Check", Check);
            info.AddValue("Account", Account);
            info.AddValue("ClientCode", ClientCode);
            info.AddValue("Instrument", Instrument);
            info.AddValue("TypeStop", TypeStop);
            info.AddValue("TypeRasch", TypeCalculation);
            info.AddValue("TypePriceForStop", TypePriceForStop);
            info.AddValue("TypeSingleOrMultiStopl", TypeSingleOrMultiStopl);

            #endregion BaseSettings

            #region StopLimit

            info.AddValue("StopLimitOtstup", StopLimitOtstup);
            info.AddValue("StopLimitOtstupType", StopLimitOtstupType);
            info.AddValue("StopLimitFromEnterMoney", StopLimitFromEnterMoney);
            info.AddValue("StopLimitSpred", StopLimitSpred);
            info.AddValue("StopLimitSpredType", StopLimitSpredType);
            info.AddValue("StopLimitIsMarketOrder", StopLimitIsMarketOrder);
            info.AddValue("StopLimitBreakeven", StopLimitBreakeven);
            info.AddValue("StopLimitBreakevenType", StopLimitBreakevenType);
            info.AddValue("StopLimitBreakOtstup", StopLimitBreakOtstup);

            #endregion StopLimit

            #region TakeProfit

            info.AddValue("TakeProfitPriceActivation", TakeProfitPriceActivation);
            info.AddValue("TakeProfitPriceActivationType", TakeProfitPriceActivationType);
            info.AddValue("TakeProfitOtstupMinMax", TakeProfitOtstupMinMax);
            info.AddValue("TakeProfitOtstupMinMaxType", TakeProfitOtstupMinMaxType);
            info.AddValue("TakeProfitSpred", TakeProfitSpred);
            info.AddValue("TakeProfitSpredType", TakeProfitSpredType);
            info.AddValue("TakeProfitFromEnterMoney", TakeProfitFromEnterMoney);
            info.AddValue("TakeProfitIsMarketOrder", TakeProfitIsMarketOrder);
            
            #endregion TakeProfit

            #region KillAndRemoveOrderFromStopOrder

            info.AddValue("KillOrderType", KillOrderType);
            info.AddValue("TimeWaitForKillOrderFromStop", TimeWaitForKillOrderFromStop);
            info.AddValue("SpredWaitForKillOrderFromStop", SpredWaitForKillOrderFromStop);

            #endregion KillAndRemoveOrderFromStopOrder

            #region LimitOrder

            info.AddValue("LimitPrice", LimitPrice);
            info.AddValue("LimitPriceType", LimitPriceType);
            info.AddValue("LimitFromEnterMoney", LimitFromEnterMoney);

            #endregion

            //info.AddValue( "TypeStopList", TypeStopList );

            //info.AddValue( "TypeRaschList", TypeRaschList );


            info.AddValue("CurrentPos", CurrentPos);
            info.AddValue("CurrentPrice", CurrentPrice);

        }
    }
}